﻿<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Rules"
           targetNamespace="http://transcriber.codeplex.com/Rules.xsd"
           elementFormDefault="qualified"
           xmlns="http://transcriber.codeplex.com/Rules.xsd"
           xmlns:mstns="http://transcriber.codeplex.com/Rules.xsd"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
  
  <!--
    Schema for rules files used by the RulesFileTranscriber
    plug-in for the Transcriber application.
    
  -->

  <!--************************************************************-->

  <xs:element name="rules" type="Rules">

    <xs:annotation>
      <xs:documentation xml:lang="en-us">
        Root element of a rules file, for use with
        the RulesFileTranscriber plug-in for the
        Transcriber application.

        Rules files contain sequences of text-replacement rules.
        Each rule in a rules file consists of a reguluar expression
        (regex) used to match portions of text and a replacement
        string to substitute for matching text in the
        output of the transcription.

        The RulesFileTranscriber.Transcribe() method processes
        each rule in the selected rules file once in the order
        they appear in the file. For each rule, all text in
        the transcription source that matches the rule's
        regex is replaced with the rule's replacement text.
        
        The replacement text is generated for each rule by applying
        MS.NET's Regex.Replace() function to the matching region
        in the source text and the body text of the rule element.
        
        By default, subsequent rules only match text that remains
        untranscribed after the execution of all previous rules.
        Any given rule can be specified with transformOutput="true"
        to override this behavior. Such rules are useful to put the
        input into some canonical form before processing the primary
        subscription rules. Rules files can contain global settings
        for how to treat unmatched text. See the documentation for
        the UnmatchedAction simple type for details.
      </xs:documentation>
    </xs:annotation>
    
  </xs:element>

  <!--************************************************************-->

  <xs:complexType name="Rules">

    <xs:annotation>
      <xs:documentation xml:lang="en-us">
        A sequence of zero or more Rule elements.
      </xs:documentation>
    </xs:annotation>

    <xs:sequence>

      <xs:choice minOccurs="0" maxOccurs="unbounded">

        <xs:element name="rule" type="Rule">
          <xs:annotation>
            <xs:documentation xml:lang="en-us">
              See the definition of the Rule complex type.
            </xs:documentation>
          </xs:annotation>
        </xs:element>

        <xs:element name="import" type="Import">
          <xs:annotation>
            <xs:documentation xml:lang="en-us">
              See the definition of the Import complex type.
            </xs:documentation>
          </xs:annotation>
        </xs:element>

      </xs:choice>

    </xs:sequence>
    
    <xs:attribute name="title" type="xs:string" use="required">
      <xs:annotation>
        <xs:documentation xml:lang="en-us">
          The title of the rules file.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>

    <xs:attribute name="caseSensitive" type="xs:boolean" use="optional" default="false">

      <xs:annotation>
        <xs:documentation xml:lang="en-us">
          A boolean value indicating whether or not the pattern matching
          algorithm will be case sensitive. Note that this maps directly
          to the inverse of the MS.NET RegexOptions.IgnoreCase value when
          used by the RulesFileTranscriber plug-in.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>

    <xs:attribute name="author" type="xs:string" use="optional">
      <xs:annotation>
        <xs:documentation xml:lang="en-us">
          The name, email address or handle of the author of the rules file.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>

    <xs:attribute name="copyright" type="xs:string" use="optional">
      <xs:annotation>
        <xs:documentation xml:lang="en-us">
          The copyright notice claimed by the author of the rules file.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>

    <xs:attribute name="unmatchedAction" type="UnmatchedAction" use="optional" default="Omit">
      <xs:annotation>
        <xs:documentation xml:lang="en-us">
          The action to take for unmatched text in the source.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>

    <xs:attribute name="replacementText" type="xs:string" use="optional" default="#164;">
      <xs:annotation>
        <xs:documentation xml:lang="en-us">
          The text with which to replace unmatched regions of the source when
          'unmatchedAction' is 'EmitReplacement.'
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>

    <xs:attribute name="displayInUserInterface" type="xs:boolean" use="optional" default="true">
      <xs:annotation>
        <xs:documentation xml:lang="en-us">
          If true, the rules file will be displayed in the list of files presented in the user
          interface. The rules file will not be displayed, otherwise. This is to allow hiding
          shared rules files that are only intended to be included in other files.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>

  </xs:complexType>

  <!--************************************************************-->

  <xs:complexType name="RulesElement">
    <xs:annotation>
      <xs:documentation xml:lang="en-us">
        Base type of Rules child elements.
      </xs:documentation>
    </xs:annotation>
  </xs:complexType>

  <!--************************************************************-->

  <xs:complexType name="Rule">

    <xs:annotation>
      <xs:documentation xml:lang="en-us">
        An individual transcription rule.
      </xs:documentation>
    </xs:annotation>

    <xs:complexContent>

      <xs:extension base="RulesElement">

        <xs:sequence>
          <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="final" type="FinalOutput"/>
            <xs:element name="intermediate" type="IntermediateResult"/>
          </xs:choice>
        </xs:sequence>

        <xs:attribute name="pattern" type="xs:string" use="required">
          <xs:annotation>
            <xs:documentation xml:lang="en-us">
              The regular expression used to select text for replacement
              by this rule. The RulesFileTranscriber plug-in assumes that
              these regular expressions will be compatible with the MS.NET
              Regex class with RegexOptions.Multiline and (possibly, depending
              on the value of the root element's 'caseSensitive' attribute)
              RegexOptions.IgnoreCase selected. Note that the use of this
              attribute and the import attribute are mutually exclusive, but
              one or the other must be supplied.
            </xs:documentation>
          </xs:annotation>
        </xs:attribute>

      </xs:extension>

    </xs:complexContent>

 </xs:complexType>

  <!--************************************************************-->

  <xs:complexType name="Import">

    <xs:complexContent>
      <xs:annotation>
        <xs:documentation xml:lang="en-us">
          Rules file element that specifies a separate file to import.
        </xs:documentation>
      </xs:annotation>
      <xs:extension base="RulesElement">
        <xs:attribute name="filename" type="xs:string" use="required">
          <xs:annotation>
            <xs:documentation xml:lang="en-us">
              Relative pathname of the rules file to import.
            </xs:documentation>
          </xs:annotation>
        </xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <!--************************************************************-->

  <xs:complexType name="OutputNode" abstract="true">

    <xs:annotation>
      <xs:documentation xml:lang="en-us">
        Base type of text replacement nodes for Rule elements.
      </xs:documentation>
    </xs:annotation>

    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute name="evaluator" type="xs:string" use="optional">
          <xs:annotation>
            <xs:documentation xml:lang="en-us">
              If present, this is the fully qualified name of a .NET type that
              implements the IRuleEvaluator interface. When the rule fires,
              an instance of this class will be instantiated and its
              IRuleEvalator.Evaluate(System.Text.RegularExpressions.Match)
              method will be invoked instead of the normal text replacement
              using the body of the Rule element. Any child elemets of the
              rule element will be ignored, in this case.
            </xs:documentation>
          </xs:annotation>
        </xs:attribute>

      </xs:extension>
    </xs:simpleContent>

  </xs:complexType>

  <!--************************************************************-->

  <xs:complexType name="FinalOutput">

    <xs:annotation>
      <xs:documentation xml:lang="en-us">
        An OutputNode that represents the final result
        of the transcription. Subsequent rules will not
        include the content of FinalOutput nodes when
        searching for possible matches.
      </xs:documentation>
    </xs:annotation>

    <xs:simpleContent>
      <xs:extension base="mstns:OutputNode"/>
    </xs:simpleContent>

  </xs:complexType>

  <!--************************************************************-->

  <xs:complexType name="IntermediateResult">

    <xs:annotation>
      <xs:documentation xml:lang="en-us">
        An OutputNode that represents an intermediate
        transformation of the original source text.
        Subsequent rules will include the content
        of IntermediateResult nodes when searching
        for possible matches.
      </xs:documentation>
    </xs:annotation>

    <xs:simpleContent>
      <xs:restriction base="mstns:OutputNode"/>
    </xs:simpleContent>

  </xs:complexType>

  <!--************************************************************-->

  <xs:simpleType name="UnmatchedAction">

    <xs:annotation>
      <xs:documentation xml:lang="en-us">
        Enumeration denoting what action to take for
        unmatched source text.
      </xs:documentation>
    </xs:annotation>

    <xs:restriction base="xs:string">

      <xs:enumeration value="Omit">
        <xs:annotation>
          <xs:documentation xml:lang="en-us">
            Omit the unmatched text from the output.
          </xs:documentation>
        </xs:annotation>
      </xs:enumeration>

      <xs:enumeration value="EmitOriginal">
        <xs:annotation>
          <xs:documentation xml:lang="en-us">
            Emit the original unmatched text
            to the output.
          </xs:documentation>
        </xs:annotation>
      </xs:enumeration>

      <xs:enumeration value="EmitReplacement">
        <xs:annotation>
          <xs:documentation xml:lang="en-us">
            Emit the replacement text specified by
            the 'replacementText' attribute of
            the root 'rules' element.
          </xs:documentation>
        </xs:annotation>
      </xs:enumeration>

    </xs:restriction>

  </xs:simpleType>

</xs:schema>